package ch.trackedbean.data;

import java.util.*;

/**
 *Factory for creating valid/invalid {@link DomA}, {@link DomB}, {@link DomC} or {@link DomD} objects.
 * 
 * @author M. Hautle
 */
public class DomFactory {
	/**
	 * Hidden constructor.
	 */
	private DomFactory() {
	}

	/**
	 * Creates and populates a valid {@link DomA} object.
	 * 
	 * @return A {@link DomA}
	 */
	public static DomA createValidDomA() {
		final DomA d = new DomA();
		fillValidDomA(d);
		return d;
	}

	public static DomA fillValidDomA(final DomA d) {
		fillDomA(d, 4, "abc", "abc", 5);
		return d;
	}

	public static DomA fillDomA(final DomA d, int numberA, String getterA, String textA, int number) {
		d.setNumberA(numberA);
		d.setGetterA(getterA);
		d.setTextA(textA);
		d.setNumber(String.valueOf(number));
		return d;
	}

	/**
	 * Creates and populates a invalide {@link DomA} object.
	 * 
	 * @return A invalide {@link DomA}
	 */
	public static DomA createInvalidDomA() {
		final DomA d = new DomA();
		fillInvalidDomA(d);
		return d;
	}

	public static DomA fillInvalidDomA(final DomA d) {
		fillDomA(d, 2, "ab", "ab", -3);
		return d;
	}

	/**
	 * Creates and populates a valid {@link DomB} object.
	 * 
	 * @return A {@link DomB}
	 */
	public static DomB createValidDomB() {
		final DomB b = new DomB();
		final List<DomA> list = new ArrayList<DomA>();
		fillValidDomB(b);
		// list part of DOM B
		list.add(fillValidDomA(new DomA()));
		list.add(fillValidDomB(new DomB()));
		list.add(fillValidDomC(new DomC()));
		b.setListB(list);
		return b;
	}

	public static DomB fillValidDomB(final DomB b) {
		fillValidDomA(b);
		b.setExternalB(5);
		b.setSimple("abc");
		return b;
	}

	/**
	 * Creates and populates a invalid {@link DomB} object.
	 * 
	 * @return A {@link DomB}
	 */
	public static DomB createInvalidDomB() {
		final DomB b = new DomB();
		final List<DomA> list = new ArrayList<DomA>();
		fillInvalidDomB(b);
		// list part of DOM B
		list.add(fillInvalidDomB(new DomB()));
		list.add(fillInvalidDomB(new DomB()));
		list.add(fillInvalidDomB(new DomB()));
		b.setListB(list);
		return b;
	}

	public static DomB fillInvalidDomB(final DomB b) {
		fillInvalidDomA(b);
		b.setExternalB(3);
		b.setSimple("ac");
		return b;
	}

	/**
	 * Creates and populates a {@link DomC} object for a mapper test.
	 * 
	 * @return A {@link DomC}
	 */
	public static DomC createMapperDomC() {
		final DomC c = new DomC();
		final DomA[] list = new DomA[3];
		fillValidDomC(c);
		// list part of DOM C
		list[0] = fillValidDomA(new DomA());
		list[1] = createValidDomB();
		list[2] = createValidDomB();
		c.setList(list);
		return c;
	}

	/**
	 * Creates and populates a valid {@link DomC} object.
	 * 
	 * @return A {@link DomC}
	 */
	public static DomC createValidDomC() {
		final DomC c = new DomC();
		final DomA[] list = new DomA[3];
		fillValidDomC(c);
		// list part of DOM C
		list[0] = fillValidDomA(new DomA());
		list[1] = fillValidDomA(new DomA());
		list[2] = fillValidDomA(new DomA());
		c.setList(list);
		return c;
	}

	public static DomC fillValidDomC(final DomC c) {
		fillValidDomA(c);
		c.setSimple("abc");
		c.setIgnore("bla");
		return c;
	}

	/**
	 * Creates and populates a invalid {@link DomC} object.
	 * 
	 * @return A {@link DomC}
	 */
	public static DomC createInvalidDomC() {
		final DomC c = new DomC();
		final DomA[] list = new DomA[3];
		fillInvalidDomC(c, "ab");
		// list part of DOM C
		list[0] = fillInvalidDomC(new DomC(), "ab");
		list[1] = fillInvalidDomC(new DomC(), "ot");
		list[2] = fillInvalidDomC(new DomC(), "ab");
		c.setList(list);
		return c;
	}

	public static DomC fillInvalidDomC(final DomC c, String textA) {
		fillInvalidDomA(c);
		c.setTextA(textA);
		c.setSimple("ab");
		c.setIgnore("bla");
		return c;
	}

	/**
	 * Creates and populates a valid {@link DomD} object.
	 * 
	 * @return A {@link DomD}
	 */
	public static DomD createValidDomD() {
		final DomD d = new DomD();
		d.setOtherDom(createValidDomB());
		final DomD d2 = new DomD();
		d2.setOtherDom(createValidDomC());
		d.setSubDom(d2);
		return d;
	}

	/**
	 * Creates and populates a invalid {@link DomD} object.
	 * 
	 * @return A {@link DomD}
	 */
	public static DomD createInvalidDomD() {
		final DomD d = new DomD();
		d.setOtherDom(createInvalidDomA());
		final DomD d2 = new DomD();
		d2.setOtherDom(createInvalidDomA());
		d.setSubDom(d2);
		return d;
	}
}
